home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / filesyst / dosfs / dosfsck_.z / dosfsck_ / dosfsck / io.c < prev    next >
C/C++ Source or Header  |  1993-05-07  |  3KB  |  137 lines

  1. /* io.c  -  Virtual disk input/output */
  2.  
  3. /* Written 1993 by Werner Almesberger */
  4.  
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <errno.h>
  11. #include <fcntl.h>
  12.  
  13. #include "dosfsck.h"
  14. #include "common.h"
  15. #include "io.h"
  16.  
  17.  
  18. typedef struct _change {
  19.     void *data;
  20.     unsigned int pos;
  21.     int size;
  22.     struct _change *next;
  23. } CHANGE;
  24.  
  25.  
  26. static CHANGE *changes,*last;
  27. static int fd,did_change = 0;
  28.  
  29.  
  30. void fs_open(char *path,int rw)
  31. {
  32.     if ((fd = open(path,rw ? O_RDWR : O_RDONLY)) < 0)
  33.     pdie("open %s",path);
  34.     changes = last = NULL;
  35.     did_change = 0;
  36. }
  37.  
  38.  
  39. void fs_read(unsigned int pos,int size,void *data)
  40. {
  41.     CHANGE *walk;
  42.     int got;
  43.  
  44.     if (lseek(fd,pos,0) != pos) pdie("Seek to %d",pos);
  45.     if ((got = read(fd,data,size)) < 0) pdie("Read %d bytes at %d",size,pos);
  46.     if (got != size) die("Got %d bytes instead of %d at %d",got,size,pos);
  47.     for (walk = changes; walk; walk = walk->next)
  48.     if (walk->pos < pos+size && walk->pos+walk->size > pos)
  49.         if (walk->pos < pos)
  50.         memcpy(data,(char *) walk->data+pos-walk->pos,min(size,
  51.           walk->size-pos+walk->pos));
  52.         else memcpy((char *) data+walk->pos-pos,walk->data,min(walk->size,
  53.           size+pos-walk->pos));
  54. }
  55.  
  56.  
  57. int fs_test(unsigned int pos,int size)
  58. {
  59.     void *scratch;
  60.     int okay;
  61.  
  62.     if (lseek(fd,pos,0) != pos) pdie("Seek to %d",pos);
  63.     scratch = alloc(size);
  64.     okay = read(fd,scratch,size) == size;
  65.     free(scratch);
  66.     return okay;
  67. }
  68.  
  69.  
  70. void fs_write(unsigned int pos,int size,void *data)
  71. {
  72.     CHANGE *new;
  73.     int did;
  74.  
  75.     if (write_immed) {
  76.     did_change = 1;
  77.     if (lseek(fd,pos,0) != pos) pdie("Seek to %d",pos);
  78.     if ((did = write(fd,data,size)) == size) return;
  79.     if (did < 0) pdie("Write %d bytes at %d",size,pos);
  80.     die("Wrote %d bytes instead of %d at %d",did,size,pos);
  81.     }
  82.     new = alloc(sizeof(CHANGE));
  83.     new->pos = pos;
  84.     memcpy(new->data = alloc(new->size = size),data,size);
  85.     new->next = NULL;
  86.     if (last) last->next = new;
  87.     else changes = new;
  88.     last = new;
  89. }
  90.  
  91.  
  92. static void fs_flush(void)
  93. {
  94.     CHANGE *this;
  95.     int size;
  96.  
  97.     while (changes) {
  98.     this = changes;
  99.     changes = changes->next;
  100.     if (lseek(fd,this->pos,0) != this->pos)
  101.         fprintf(stderr,"Seek to %d failed: %s\n  Did not write %d bytes.\n",
  102.           this->pos,strerror(errno),this->size);
  103.     else if ((size = write(fd,this->data,this->size)) < 0)
  104.         fprintf(stderr,"Writing %d bytes at %d failed: %s\n",this->size,
  105.           this->pos,strerror(errno));
  106.         else if (size != this->size)
  107.             fprintf(stderr,"Wrote %d bytes instead of %d bytes at %d."
  108.               "\n",size,this->size,this->pos);
  109.     free(this->data);
  110.     free(this);
  111.     }
  112. }
  113.  
  114.  
  115. int fs_close(int write)
  116. {
  117.     CHANGE *next;
  118.     int changed;
  119.  
  120.     changed = !!changes;
  121.     if (write) fs_flush();
  122.     else while (changes) {
  123.         next = changes->next;
  124.         free(changes->data);
  125.         free(changes);
  126.         changes = next;
  127.     }
  128.     if (close(fd) < 0) pdie("closing file system");
  129.     return changed || did_change;
  130. }
  131.  
  132.  
  133. int fs_changed(void)
  134. {
  135.     return !!changes || did_change;
  136. }
  137.